package com.hejing.泛型在继承中的体现及通配符的使用;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * ClassName: GenericTest01
 * Package: com.hejing.泛型在继承中的体现及通配符的使用
 * Description:
 *
 * @Author: HeJing
 * @Create: 2023-05-22 11:24
 * @Version: 1.0
 */
public class GenericTest01 {

    /**
     * 初识通配符
     */
    @Test
    public void test01(){

        List<?> list = null;
        List<Object> list1 = null;
        List<String> list2 = null;

        list = list1;
        list = list2;

        show(list1);
        show(list2);
    }

    public void show(List<?> list) {
        for(Object obj: list) {
            System.out.println(obj);
        }
    }

    /**
     * 测试: 无限制条件的通配符使用:
     */
    @Test
    public void test02(){
        List<?> list = null;
        List<String> list1 = new ArrayList<>();
        list1.add("AA");
        list = list1;

        // 读取数据 (以集合为例)
        Object obj = list.get(0);
        System.out.println(obj);

        // 添加数据 (以集合为例)
        // list.add("BB"); 使用通配符则不能添加数据(除null)
        // 特例: 可以将null添加到集合中，但是一般没有什么意义。
        list.add(null);

        System.out.println(list1);
    }

    /**
     * 测试: 有限制条件的通配符的使用:
     *      ? extends A:
     *      ? super A:
     */
    @Test
    public void test03(){
        // ? extends Father : 可以将Father及其子类的对象赋值给该通配符类的引用
        List<? extends Father> list = null;
        List<Object> list1 = null;
        List<Father> list2 = null;
        List<Son> list3 = null;

        // list = list1;
        list = list2;
        list = list3;
    }

    /**
     * 针对于 ? extends A的读写操作
     */
    @Test
    public void test3_1(){
        List<? extends Father> list = null;

        List<Father> list1 = new ArrayList<>();
        list1.add(new Father());

        list = list1;
        // 读取数据，可以
        Father father = list.get(0);

        // 写入数据，不可以，例外: null
        list.add(null);
        // list.add(new Father());  报错
        // list.add(new Son()); 报错
    }

    @Test
    public void test05(){
        // ? super Father : 可以将Father及其父类的对象赋值给该通配符类的引用
        List<? super Father> list = null;
        List<Object> list1 = null;
        List<Father> list2 = null;
        List<Son> list3 = null;

        list = list1;
        list = list2;
        // list = list3;
    }

    @Test
    public void test4_1(){
        List<? super Father> list = null;
        List<Father> list1 = new ArrayList<>();
        list1.add(new Father());

        list = list1;
        // 读取数据
        Object obj = list.get(0);

        // 写入数据: 可以将Father及其子类对象添加进来。
        list.add(null);
        // list.add(new Object());
        list.add(new Father());
        list.add(new Son());

    }


}

































